#pragma once

#include <atlframe.h>
#include <atlcrack.h>
#include <atlmisc.h>
#include <atlscrl.h>
#include <atlctrls.h>
#include "Theme.h"

template <class T, class TBase = CStatic, class TWinTraits = ATL::CControlWinTraits>
class CSkinnedTextImpl : public ATL::CWindowImpl< T, TBase, TWinTraits>
{
public:
  DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName())

  CSkinnedTextImpl(COLORREF clrText, CFontHandle fntText, CBrushHandle brBackground)
  { m_clrText = clrText; m_fntText = fntText; m_brBackground = brBackground; }

	HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
			DWORD dwStyle = WS_CHILD | WS_BORDER | WS_VISIBLE, DWORD dwExStyle = 0,
			ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL)
	{
		return CWindowImpl<T, TBase, TWinTraits>::Create(hWndParent, rect, szWindowName, dwStyle, dwExStyle, MenuOrID, lpCreateParam);
	}

  void SetStyle(COLORREF clrText, CFontHandle fntText, CBrushHandle brBackground)
  { m_clrText = clrText; m_fntText = fntText; m_brBackground = brBackground; }

// Message map and handlers
	BEGIN_MSG_MAP(CSkinnedTextImpl)
    MESSAGE_HANDLER(WM_HDCPAINT, OnHdcPaint)

    MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnColorStatic)
    MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown)
    MESSAGE_HANDLER(WM_KEYUP, OnKeyUp)
	END_MSG_MAP()

  LRESULT OnHdcPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  {
    CRect rClient;
    GetClientRect(&rClient);
    CDCHandle dc((HDC)wParam);
    dc.FillRect(&rClient, m_brBackground);
    dc.SetTextColor(m_clrText);
    HFONT hfPrev = dc.SelectFont(m_fntText);
    dc.SetBkMode(TRANSPARENT);
    CString sText;
    GetWindowText(sText);
    dc.DrawText(sText, sText.GetLength(), &rClient, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS);
    dc.SelectFont(hfPrev);
    return bHandled = TRUE;
  }

  LRESULT OnColorStatic(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
  {
    CDCHandle dc((HDC)wParam);
    dc.SetBkMode(TRANSPARENT);
    dc.SetTextColor(m_clrText);
    dc.SelectFont(m_fntText);
    return (LRESULT)m_brBackground.m_hBrush;
  }

  LRESULT OnKeyDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  {
    SendMessage(::GetParent(m_hWnd), uMsg, wParam, lParam);
    return bHandled = FALSE;
  }

  LRESULT OnKeyUp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  {
    SendMessage(::GetParent(m_hWnd), uMsg, wParam, lParam);
    return bHandled = FALSE;
  }

protected:
  COLORREF     m_clrText;
  CFontHandle  m_fntText;
  CBrushHandle m_brBackground;
};

class CSkinnedText : public CSkinnedTextImpl<CSkinnedText>
{
public:
	CSkinnedText(COLORREF clrText = CTheme::clrPopupHeader, CFontHandle fntText = CTheme::fntPopupHeader.font.m_hFont, CBrushHandle brBackground = CTheme::brPopupHeader.m_hBrush) : 
		CSkinnedTextImpl<CSkinnedText>(clrText, fntText, brBackground)
	{ }
};